﻿using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

namespace Zijian666
{
    /// <summary>
    /// 阻塞字符串队列
    /// </summary>
    internal class BlockedStringQueue : IDisposable
    {
        // 字符串缓存内部实例
        private readonly BufferBlock<string> _buffer = new();
        // 最大缓存个数,超过后将丢弃最早的未被获取的字符串
        private readonly int _maxBuffSize;
        // 施放标识:0=未释放;1=已释放
        private long _disposed = 0;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="maxBuffSize">最大缓存数</param>
        public BlockedStringQueue(int maxBuffSize = 255) => _maxBuffSize = maxBuffSize;

        /// <summary>
        /// 将字符串添加到队列
        /// </summary>
        public async Task Enqueue(string str)
        {
            if (_disposed == 1)
            {
                return;
            }
            await _buffer.SendAsync(str);
            while (_buffer?.Count > _maxBuffSize)
            {
                _buffer.TryReceive(out _);
            }
        }

        /// <summary>
        /// 从队列顶端获取一个字符串,如果队列为空,则无限期等待
        /// </summary>
        /// <returns></returns>
        public string? WaitDequeue()
        {
            if (_disposed == 1)
            {
                return null;
            }
            var str = _buffer.Receive();
            if (_disposed == 1)
            {
                return null;
            }
            return str;
        }

        /// <summary>
        /// 释放队列
        /// </summary>
        public void Dispose()
        {
            if (_disposed == 1)
            {
                return;
            }
            var i = Interlocked.Exchange(ref _disposed, 1);
            if (i != 0)
            {
                return;
            }
            try
            {

                _buffer.SendAsync("@exit");
                _buffer.Complete();
            }
            catch { }
        }
    }
}
